package Logica.Textures;

import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;

import javax.imageio.ImageIO;

/** 
 * Manejador de Skins.
 * Esta clase se encarga de buscar las texturas correspondientes y generar los Sprites para el juego.
 * El nombre del skin representa la carpeta en la cual se buscan las texturas.
 * Data/Textures/NOMBRE
 * 
 * @author Ignacio del Barrio, Ignacio Jocano, Alexis Aguilera
 */
public abstract class SkinManager {

	/** Nombre del Skin */
	private String name;
	/** Mapeo Grafico en cargado de Mapear cada Entidad con su Sprite */
	private HashMap<String, Sprite> skin;
	
	public SkinManager(String name) {
		this.name = name;
		skin = new HashMap<String, Sprite>();
	}
	
	/**
	 * Busca una textura en los datos del juego y genera un Sprite a partir de ella.
	 * 
	 * @param ref Referencia a la imagen a ser utilizda por el Sprite
	 * @return Un Sprite conteniendo una imagen accelerada de la referencia
	 */
	public Sprite get(String ref) {
		// Si ya tenemos cacheada la imagen
		// entonces simplemente devolvemos la version existente
		if (skin.get(ref) != null) {
			return skin.get(ref);
		}
		
		// Sino buscamos la imagen en los datos
		// loader
		BufferedImage sourceImage = null;
		
		try {
			// ClassLoader.getResource() se asegura de tomar los datos del lugar correcto.
			// Donde este el ".class" o el ".jar"
			URL url = this.getClass().getClassLoader().getResource("Data/Textures/"+name+"/"+ref);
			
			if (url == null) {
				fail("Can't find ref: "+ref);
			}
			
		// use ImageIO to read the image in
			sourceImage = ImageIO.read(url);
		} catch (IOException e) {
			fail("Failed to load: "+ref);
		}
		
		// create an accelerated image of the right size to store our sprite in
		GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
		BufferedImage image = gc.createCompatibleImage(sourceImage.getWidth(),sourceImage.getHeight(),Transparency.BITMASK);
		
		// draw our source image into the accelerated image
		image.getGraphics().drawImage(sourceImage,0,0,null);
		
		// create a sprite, add it the cache then return it
		Sprite sprite = new Sprite(image);
		skin.put(ref,sprite);
		
		return sprite;		
	}
	/**
	 * Utility method to handle resource loading failure
	 * 
	 * @param message The message to display on failure
	 */
	private void fail(String message) {
		// we're pretty dramatic here, if a resource isn't available
		// we dump the message and exit the game
		System.err.println(message);
		System.exit(0);
	}
}
